﻿/*
 * 插件模式开发/模块化框架
 * 反射
 *
 * 标准:
 * 1.定一个标准的基类或接口
 * 2.定义少量的方法,字段
 * 3.扫描所有程序集,实现筛选掉系统的程序集
 */

using System.Reflection;
using Newtonsoft.Json;
using 反射高级.IPlugin;



var assemblyFilePaths = Directory.EnumerateFiles(AppContext.BaseDirectory, "*.dll");

var assemblyList = new List<Assembly>();

foreach (var assemblyFile in assemblyFilePaths)
{
    Console.WriteLine($"加载程序集:{assemblyFile}");
    var assembly = Assembly.LoadFile(assemblyFile);
    assemblyList.Add(assembly);
}

// 获取所有的公开类
var allPublicTypes = assemblyList.SelectMany(x => x.GetExportedTypes());

Console.WriteLine($"allPublicTypes的数量:{allPublicTypes.Count()}");

foreach (var allPublicType in allPublicTypes.Where(x => x.Name.Contains("Plugin")))
{
    Console.WriteLine($"{allPublicType.Name}继承了{JsonConvert.SerializeObject(allPublicType.GetInterfaces().ToList())}");
}

// 获取所有继承IPlugin的类
var allPluginTypes = allPublicTypes.Where(x => x.IsAssignableTo(typeof(IPluginService)));

Console.WriteLine($"继承了{nameof(IPluginService)}的allPluginTypes的数量:{allPluginTypes.Count()}");

foreach (var allPluginType in allPluginTypes)
{
    var plugin = Activator.CreateInstance(allPluginType) as IPluginService;
    plugin?.Execute();
}

//啧啧,这个只能分开多个程序集来写 不知道为啥写到一个程序集不行

//合并写法
//assemblyList.SelectMany(x => x.GetExportedTypes()).Where(x => x.IsAssignableTo(typeof(IPluginService))).Select(x => (IPluginService)Activator.CreateInstance(x)).ToList().ForEach(x => x?.Execute());

